home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / networke / xfirepow.000 / xfirepow / xfirepower-0.84 / client / redraw3d.c < prev    next >
C/C++ Source or Header  |  1995-11-22  |  11KB  |  491 lines

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include "Wlib.h"
  4. #include "data.h"
  5. #include "struct.h"
  6. #include "defs.h"
  7. #include "images.h"
  8.  
  9. #define WIN3DHEIGHT 200
  10. #define WIN3DWIDTH 320
  11.  
  12. int t_image_nums[NUMTERRAINS] = {
  13.     I_GRASS,
  14.     I_ROAD,
  15.     I_TREE,
  16.     I_POST,
  17.     I_POST,
  18.     I_WALL_T,
  19.     I_WALL_R,
  20.     I_WALL_TR,
  21.     I_WALL_B,
  22.     I_WALL_TB,
  23.     I_WALL_BR,
  24.     I_WALL_TBR,
  25.     I_WALL_L,
  26.     I_WALL_TL,
  27.     I_WALL_RL,
  28.     I_WALL_TRL,
  29.     I_WALL_BL,
  30.     I_WALL_TBL,
  31.     I_WALL_BRL,
  32.     I_WALL_TBRL,
  33.     I_WATER,
  34.     I_CRATER,
  35.     I_BASE1,
  36.     I_BASE2,
  37.     I_BRIDGE,
  38. };
  39.  
  40. unsigned char get_dir(int x1, int y1, int x2, int y2)
  41. {
  42.     return (unsigned char) (atan2((double) (x2 - x1),
  43.                      (double) (y1 - y2)) / 3.14159 * 128.);
  44. }
  45.  
  46. int translate_point(W_Point *point)
  47. {
  48.     double ax, ay, ox, oy, xx;
  49.     double px, py;
  50.     double my=(double)me->p_y-Sin[me->p_dir]*(double)(focalDist),
  51.         mx=(double)me->p_x-Cos[me->p_dir]*(double)(focalDist);
  52.     unsigned char ang;
  53.     double dist;
  54.  
  55.     px = point->x; py = point->y;
  56.  
  57.     if(mx == px && my == py)
  58.     ang = 0;
  59.     else
  60.     ang = get_dir(mx, my, px, py);
  61.     ang = me->p_dir - ang;
  62.  
  63.     dist = (double) hypot((double)(mx - px), (double)(my - py));
  64.     ay = Sin[ang] * dist;
  65.     ax = Cos[ang] * dist;
  66.  
  67.     if(!ay)
  68.     ay = -0.1;
  69.     ox=(ax*focalDist)/ay;
  70.  
  71.     if(ay > 0)
  72.     ox = -ox;
  73.     xx = WIN3DWIDTH/2 + ox;
  74.     point->x = rint(xx);
  75.  
  76.     if(!ay)
  77.     oy = 1000000;
  78.     else
  79.     oy = (focalDist*viewHeight)/ay;
  80.     if(oy > 0)
  81.     oy = -oy;
  82.     point->y = WIN3DHEIGHT/2.0-oy;
  83.  
  84.     point->x /= 1;
  85.     point->y /= 1;
  86.     return 1;
  87. }
  88.  
  89. void render_square(int x, int y)
  90. {
  91.     W_Point points[4];
  92.     int gx, gy;
  93.     int color;
  94.     unsigned char angdiff;
  95.     int mx, my;
  96.  
  97.     mx=me->p_x-Cos[me->p_dir]*(GRIDWIDTH<<4);
  98.     my=me->p_y-Sin[me->p_dir]*(GRIDHEIGHT<<4);
  99.  
  100.     gx = x * (GRIDWIDTH<<4);
  101.     gy = y * (GRIDHEIGHT<<4);
  102.  
  103.     angdiff = me->p_dir - (get_dir(mx, my,
  104.                 gx + (GRIDWIDTH << 2), gy + (GRIDHEIGHT << 2)));
  105.     if(angdiff < 64 || angdiff > 192) {
  106.     /* world coords */
  107.     points[0].x = gx;
  108.     points[0].y = gy;
  109.     
  110.     points[1].x = gx+(GRIDWIDTH<<4);
  111.     points[1].y = gy;
  112.     
  113.     points[2].x = gx+(GRIDWIDTH<<4);
  114.     points[2].y = gy+(GRIDHEIGHT<<4);
  115.     
  116.     points[3].x = gx;
  117.     points[3].y = gy+(GRIDHEIGHT<<4);
  118.     
  119.     translate_point(&points[0]);
  120.     translate_point(&points[1]);
  121.     translate_point(&points[2]);
  122.     translate_point(&points[3]);
  123.  
  124.     switch(map[x][y]) {
  125.       case T_WATER:
  126.         color = W_Blue;
  127.         break;
  128.       case T_GRASS:
  129.         color = W_Green;
  130.         break;
  131.       case T_TREE:
  132.         color = W_DarkGreen;
  133.         break;
  134.       case T_ROAD:
  135.       case T_BRIDGE:
  136.       case T_BASE1:
  137.       case T_BASE2:
  138.         color = W_Brown;
  139.         break;
  140.       default:
  141.         color = W_Red;
  142.         break;
  143.     }
  144.     if(!(points[0].y <= 0 || points[1].y <= 0 || points[1].y <= 0 || points[2].y <= 0))
  145.         W_DrawPolygon(win3d, points, 4, color);
  146.     }
  147. }
  148.  
  149. void draw_local(int x, int y)
  150. {
  151.     int i,j;
  152.     W_Image *img;
  153.  
  154.     if(W_IsMapped(win3d))
  155.     W_FillArea(win3d, 0, 0, 320, 200, W_Black);
  156.  
  157.     for(i=x/GRIDWIDTH; i<=(x/GRIDWIDTH+1) + WINWIDTH/GRIDWIDTH;i++) {
  158.     for(j=y/GRIDHEIGHT; j <= (y/GRIDHEIGHT+1) + WINHEIGHT/GRIDHEIGHT; j++) {
  159.         switch(map[i][j]) {
  160.           case T_TREE:
  161.         img = t_shapes[T_GRASS];
  162.         break;
  163.           case T_BASE1:
  164.           case T_BASE2:
  165.         img = t_shapes[T_ROAD];
  166.         break;
  167.           default:
  168.         img = t_shapes[(int)map[i][j]];
  169.         break;
  170.         }
  171.         W_DrawImageNoClip(cwin, i*GRIDWIDTH-x, j*GRIDHEIGHT-y, counter, img, W_Green);
  172.         if(W_IsMapped(win3d))
  173.         render_square(i, j);
  174.     }
  175.     }
  176. }
  177.  
  178.     
  179. void draw_overlays(int x, int y)
  180. {
  181.     int i,j;
  182.  
  183.     for(i=x/GRIDWIDTH; i<=(x/GRIDWIDTH+1) + WINWIDTH/GRIDWIDTH;i++) {
  184.     for(j=y/GRIDHEIGHT; j <= (y/GRIDHEIGHT+1) + WINHEIGHT/GRIDHEIGHT; j++) {
  185.         switch(map[i][j]) {
  186.           case T_TREE:
  187.           case T_BASE1:
  188.           case T_BASE2:
  189.         W_DrawImage(cwin, i*GRIDWIDTH-x, j*GRIDHEIGHT-y, 0, t_shapes[(int)map[i][j]], W_Green);
  190.         break;
  191.           default:
  192.         break;
  193.         }
  194.     }
  195.     }
  196. }
  197.  
  198.  
  199. void draw_players(int cx, int cy)
  200. {
  201.     int dx, dy;
  202.     int i;
  203.     player *p;
  204.     W_Image *img;
  205.     W_Color color;
  206.     char buf[20];
  207.  
  208.     for(i=0,p=&players[0];i<MAXPLAYERS;i++,p++) {
  209.     if(p->p_status == PALIVE) {
  210.         dx = (p->p_x>>4) - cx - myTankImg->width/2;
  211.         dy = (p->p_y>>4) - cy - myTankImg->height/2;
  212.  
  213.         if(p == me) {
  214.         my_dx = dx + myTankImg->width/2;
  215.         my_dy = dy + myTankImg->width/2;
  216.         }
  217.  
  218.         if(dx>(-((int)myTankImg->width)) &&
  219.            dy >(-((int)myTankImg->height)) &&
  220.            dx < WINWIDTH &&
  221.            dy < WINHEIGHT) {
  222.         if(p == me)
  223.             img = myTankImg;
  224.         else
  225.             img = teamTankImg[(p->p_team == 0) ? 0 : 1];
  226.         W_DrawImage(cwin, dx, dy, (p->p_dir+8) >> 4, img, W_Cyan);
  227.         color = (p==me) ? W_White : W_Yellow;
  228.         if(namesOnTanks)
  229.             sprintf(buf, "%s(%d)", players[i].p_name, i);
  230.         else
  231.             sprintf(buf, "%d", i);
  232.         W_MaskText(cwin, dx + (myTankImg->width/2)-(strlen(buf)*W_Textwidth)/2, dy-W_Textheight, 
  233.                color, buf, strlen(buf), W_BoldFont);
  234.         }
  235.     } else if(p->p_expfuse > 0) {
  236.         dx = (p->p_x>>4) - cx - expImg->width/2;
  237.         dy = (p->p_y>>4) - cy - expImg->height/2;
  238.         if(dx>(-((int)expImg->width)) &&
  239.            dy >(-((int)expImg->height)) &&
  240.            dx < WINWIDTH &&
  241.            dy < WINHEIGHT) {
  242.         W_DrawImage(cwin, dx, dy, EXPFUSE - p->p_expfuse, expImg, W_Red);
  243.         }
  244.         p->p_expfuse--;
  245.     }
  246.     }
  247. }
  248.  
  249. void draw_shells(int cx, int cy)
  250. {
  251.     int dx, dy;
  252.     int i;
  253.     shell *s;
  254.     W_Image *img;
  255.  
  256.     for(i=0,s=&shells[0];i<SHELLSPERPLAYER * MAXPLAYERS;i++,s++) {
  257.     if(s->s_status == SALIVE) {
  258.         dx = (s->s_x>>4) - cx;
  259.         dy = (s->s_y>>4) - cy;
  260.         if(dx > 0 &&
  261.            dy > 0 &&
  262.            dx < WINWIDTH &&
  263.            dy < WINHEIGHT) {
  264.         img = shellImg;
  265.         W_DrawImage(cwin, dx - img->width/2, dy - img->height/2, s->s_fuse, img, W_Cyan);
  266.         } else
  267.         s->s_status = SDEAD;
  268.     }
  269.     }
  270. }
  271.  
  272. void draw_shell_exps(int cx, int cy)
  273. {
  274.     int dx, dy;
  275.     int i;
  276.     shell *s;
  277.     W_Image *img;
  278.  
  279.     for(i=0,s=&shells[0];i<SHELLSPERPLAYER * MAXPLAYERS;i++,s++) {
  280.     if(s->s_status == SEXPLODE) {
  281.         dx = (s->s_x>>4) - cx;
  282.         dy = (s->s_y>>4) - cy;
  283.         if(dx > 0 &&
  284.            dy > 0 &&
  285.            dx < WINWIDTH &&
  286.            dy < WINHEIGHT) {
  287.         img = mineExpImg;
  288.         W_DrawImage(cwin, dx - img->width/2, dy - img->height/2, s->s_fuse, img, W_Cyan);
  289.         s->s_fuse++;
  290.         if(s->s_fuse >= img->frames)
  291.             s->s_status = SDEAD;
  292.         } else
  293.         s->s_status = SDEAD;
  294.     }
  295.     }
  296. }
  297.  
  298. void draw_flags(int cx, int cy)
  299. {
  300.     int dx, dy;
  301.     int i;
  302.     flag *f;
  303.  
  304.     for(i=0,f=&flags[0];i<NUMFLAGS;i++,f++) {
  305.     dx = (f->f_x >> 4) - cx;
  306.     dy = (f->f_y >> 4) - cy;
  307.     if(dx > 0 &&
  308.        dy > 0 &&
  309.        dx < WINWIDTH &&
  310.        dy < WINHEIGHT)
  311.         W_DrawImage(cwin, dx - flagImg[f->f_team]->width/2, dy - flagImg[f->f_team]->height/2, 
  312.             0, flagImg[f->f_team], W_Cyan);
  313.     }
  314. }
  315.  
  316. void draw_mines(int cx, int cy)
  317. {
  318.     int dx, dy;
  319.     int i;
  320.     mine *mi;
  321.     W_Image *img;
  322.  
  323.     for(i=0;i<MAXPLAYERS * MINESPERPLAYER;i++) {
  324.     if(mines[i].mi_status != MIEMPTY) {
  325.         mi = &mines[i];
  326.         dx = (mi->mi_x >> 4) - cx;
  327.         dy = (mi->mi_y >> 4) - cy;
  328.         if(dx > 0 && 
  329.            dy > 0 &&
  330.            dx < WINWIDTH &&
  331.            dy < WINHEIGHT) {
  332.         if(mines[i].mi_status == MILIVE)
  333.             img = mineImg;
  334.         else
  335.             img = mineExpImg;
  336.         W_DrawImage(cwin, dx - img->width/2, dy - img->height/2,
  337.                 mines[i].mi_fuse, img, W_Red);
  338.         }
  339.         if(mines[i].mi_status == MIEXPLODE) {
  340.         mines[i].mi_fuse++;
  341.         if(mines[i].mi_fuse >= mineExpImg->frames)
  342.             mines[i].mi_status = MIEMPTY;
  343.         }
  344.     }
  345.     }
  346. }
  347.  
  348. void draw_build_marker(int cx, int cy)
  349. {
  350.     int mapx, mapy, dx, dy;
  351.  
  352.     if(me->p_speed == 0 && me->p_trees && showBuildMarker) {
  353.     mapx = (me->p_x >> 4)/GRIDWIDTH;
  354.     mapy = (me->p_y >> 4)/GRIDHEIGHT;
  355.     if(me->p_dir < 32 || me->p_dir > 224)
  356.         mapy--;
  357.     else if(me->p_dir < 96)
  358.         mapx++;
  359.     else if(me->p_dir < 160)
  360.         mapy++;
  361.     else
  362.         mapx--;
  363.     if(mapx < 0 || mapy < 0 || mapx >= map_info.m_width || mapy >= map_info.m_height)
  364.         return;
  365.     dx = mapx*GRIDWIDTH-cx;
  366.     dy = mapy*GRIDHEIGHT-cy;
  367.     W_MakeLine(cwin, dx, dy, dx+GRIDWIDTH-1, dy, W_Yellow);
  368.     W_MakeLine(cwin, dx+GRIDWIDTH-1, dy, dx+GRIDWIDTH-1, dy+GRIDHEIGHT-1, W_Yellow);
  369.     W_MakeLine(cwin, dx, dy+GRIDHEIGHT-1, dx+GRIDWIDTH-1, dy+GRIDHEIGHT-1, W_Yellow);
  370.     W_MakeLine(cwin, dx, dy+GRIDHEIGHT-1, dx, dy, W_Yellow);
  371.     }
  372. }
  373.  
  374. int mapx[MAXPLAYERS], mapy[MAXPLAYERS];
  375.  
  376. void map_square(int x, int y)
  377. {
  378.     W_Color color;
  379.  
  380.     switch(map[x][y]) {
  381.       case T_GRASS:
  382.     color = W_DarkGreen;
  383.     break;
  384.       case T_TREE:
  385.     color = W_Green2;
  386.     break;
  387.       case T_ROAD:
  388.       case T_BRIDGE:
  389.     color = W_Brown;
  390.     break;
  391.       case T_WATER:
  392.     color = W_Blue;
  393.     break;
  394.       case T_CRATER:
  395.     color = W_Yellow;
  396.     break;
  397.       default:
  398.     if(map[x][y] >= T_GWALL && map[x][y] <= T_WALL_TBRL)
  399.         color = W_Red;
  400.     else
  401.         color = W_Grey;
  402.     }
  403.     W_FillArea(mapwin, x*map_pixel, y*map_pixel, map_pixel, map_pixel, color);
  404. }
  405.  
  406. void update_map()
  407. {
  408.     int i,x,y;
  409.     W_Color color;
  410.  
  411.     for(i=0;i<MAXPLAYERS;i++) {
  412.     if(mapx[i] >= 0 && mapy[i] >= 0) {
  413.         map_square(mapx[i], mapy[i]);
  414.     }
  415.     if(players[i].p_status == PALIVE) {
  416.         x = (players[i].p_x >> 4) / GRIDWIDTH;
  417.         y = (players[i].p_y >> 4) / GRIDHEIGHT;
  418.         if(&players[i] == me)
  419.         color = W_White;
  420.         else if(players[i].p_team == 0)
  421.         color = W_Blue;
  422.         else
  423.         color = W_Red;
  424.         W_FillArea(mapwin, x*map_pixel, y*map_pixel, map_pixel, map_pixel, W_White);
  425.         W_MakeLine(mapwin, x*map_pixel, y*map_pixel, 
  426.                x*map_pixel + map_pixel - 1, y*map_pixel + map_pixel - 1, color);
  427. /*
  428.         W_DrawPoint(mapwin, x*2, y*2, W_White);
  429.         W_DrawPoint(mapwin, x*2+1, y*2, W_White);
  430.         W_DrawPoint(mapwin, x*2, y*2+1, color);
  431.         W_DrawPoint(mapwin, x*2+1, y*2+1, color);
  432. */
  433.         mapx[i] = x;
  434.         mapy[i] = y;
  435.     } else {
  436.         mapx[i] = -1;
  437.     }
  438.     }
  439. }
  440.  
  441. void redraw_map()
  442. {
  443.     int x, y;
  444.  
  445.     for(x=0;x<map_info.m_width;x++) {
  446.     for(y=0;y<map_info.m_height;y++) {
  447.         map_square(x,y);
  448.     }
  449.     }
  450.  
  451.     update_map();
  452. }
  453.  
  454. void init_terrain()
  455. {
  456.     int i;
  457.  
  458.     for(i=0;i<NUMTERRAINS;i++)
  459.     t_shapes[i] = getImage(t_image_nums[i]);
  460. }
  461.  
  462. void do_redraw()
  463. {
  464.     int cx, cy;
  465.  
  466.     if(!displayoff) {
  467.     cx = (me->p_x>>4)-WINWIDTH/2;
  468.     cy = (me->p_y>>4)-WINHEIGHT/2;
  469.     if(cx < 0) cx = 0;
  470.     else if(cx > GRIDWIDTH * map_info.m_width - WINWIDTH)
  471.         cx = GRIDWIDTH * map_info.m_width - WINWIDTH;
  472.     if(cy < 0) cy = 0;
  473.     else if(cy > GRIDHEIGHT * map_info.m_height - WINHEIGHT)
  474.         cy = GRIDHEIGHT * map_info.m_height - WINHEIGHT;
  475.     
  476.     draw_local(cx,cy);
  477.     draw_mines(cx, cy);
  478.     draw_shells(cx, cy);
  479.     draw_players(cx,cy);
  480.     draw_overlays(cx,cy);
  481.     draw_flags(cx, cy);
  482.     draw_shell_exps(cx, cy);
  483.     draw_build_marker(cx, cy);
  484.  
  485.     W_DisplayBuffer(cwin);
  486.     W_DisplayBuffer(win3d);
  487.     W_Flush();
  488.     update_map();
  489.     }
  490. }
  491.